﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.Drawing;

namespace Antlers
{
	internal class ThumbnailIO
	{
		public delegate void ThumbnailReadyCallback(Thumbnail loadedThumbnail, IOType type);

		internal enum IOType
		{
			Image,
			KeywordRead,
			KeywordWrite,
		}

		private ThumbnailIO()
		{
		}

		static ThumbnailIO()
		{
			Instance = new ThumbnailIO();
		}

		private static ThumbnailIO Instance
		{
			get;
			set;
		}

		private Dictionary<string, LinkedListNode<Thumbnail>> Hash
		{
			get;
			set;	
		}

		internal static Thumbnail PrepareThumbnail(string path)
		{
			LinkedListNode<Thumbnail> node;

			if (Instance.Hash.ContainsKey(path))
			{
				Instance.Hash.TryGetValue(path, out node);
			}
			else
			{
				Thumbnail thumbnail = new Thumbnail(path);
				node = new LinkedListNode<Thumbnail>(thumbnail);
				Instance.Hash.Add(path, node);
			}

			return node.Value;
		}

		internal static void PrepareResource(Thumbnail thumbnail, IOType type, ThumbnailReadyCallback callback)
		{
			PrepareResource(new Thumbnail[] { thumbnail }, type, callback);
		}

		internal static void PrepareResource(ICollection<Thumbnail> list, IOType type, ThumbnailReadyCallback callback)
		{
			ThumbnailIOContextList contextList = new ThumbnailIOContextList(list, callback);

			switch (type)
			{
				case IOType.Image:
					new OperationQueue<ThumbnailIOContext>(contextList, PrepareImage).Start();
					break;
				case IOType.KeywordRead:
					new OperationQueue<ThumbnailIOContext>(contextList, PrepareKeywords).Start();
					break;
			}
		}

		private static void PrepareImage(ThumbnailIOContext context)
		{
			context.Thumbnail.EnsureUpdateImage();
			context.Callback(context.Thumbnail, IOType.Image);
		}

		private static void PrepareKeywords(ThumbnailIOContext context)
		{
			context.Thumbnail.EnsureUpdateKeywords();
			context.Callback(context.Thumbnail, IOType.KeywordRead);
		}

		private class ThumbnailIOContext
		{
			public ThumbnailIOContext(Thumbnail thumbnail, ThumbnailReadyCallback callback)
			{
				Thumbnail = thumbnail;
				Callback = callback;
			}

			public Thumbnail Thumbnail
			{
				get;
				set;
			}

			public ThumbnailReadyCallback Callback
			{
				get;
				set;
			}
		}

		private class ThumbnailIOContextList : List<ThumbnailIOContext>
		{
			public ThumbnailIOContextList(ICollection<Thumbnail> list, ThumbnailReadyCallback callback)
				: base(list.Count)
			{
				foreach (Thumbnail thumbnail in list)
				{
					Add(new ThumbnailIOContext(thumbnail, callback));
				}
			}
		}
	}
}
